package old_Core;

import MathCore.Real;
import java.util.Vector;

public class Matrix extends Object {
	
	public Real [][] matrix;
	static Real tmp1 = new Real();
	static Real tmp[] = new Real [7];
	
	void initTmp()
	{
		for(int i = 0; i < tmp.length; i++)
		{
			tmp[i] = new Real(0);
		}
	}
	
	public Matrix(Real[][] m)
	{
		matrix=m;
		initTmp();
	}
	
	public Matrix(Vector v)
	{
		int w = v.size();
		int h = ((Vector)v.firstElement()).size();
		
		matrix = new Real [w][h];
		
		for(int i = 0; i < w; i++)
		{
			for(int j = 0; j < h; j++)
			{
				matrix[i][h-j-1] = new Real((Real) ((Vector)v.elementAt(i)).elementAt(j));
			}	
		}
		
		initTmp();
	}
	
	public Matrix(int w, int h)
	{
		matrix = new Real [w][h];
		
		for(int i = 0; i < w; i++)
		{
			for(int j = 0; j < h; j++)
			{
				matrix[i][j] = new Real(Real.NAN);
			}	
		}
		
		initTmp();
	}

	public Real get(int number)
	{
		return matrix[number % getH()][number - (number % getH())];
	}
	
	public int getW()
	{
		try{
			return matrix[0].length;
		}catch(ArrayIndexOutOfBoundsException e){
			return 0;
		}
	}
	
	public int getH()
	{
		return matrix.length;
	}
	
	public String toString()
	{	
		StringBuffer out = new StringBuffer();
		out.append("{");
		
		for(int i = 0; i < matrix.length; i++)
		{
			out.append("{ ");
			for(int j = 0; j < matrix[i].length; j++) out.append(matrix[i][j].toString()).append(' ');
			out.append("}");
		}
		
		out.append("}");
		
		return out.toString();
	}
	
	public void set(Matrix original)
	{
		for(int i = 0; i < Math.min(matrix.length, original.matrix.length); i++)
			for(int j = 0; j < Math.min(matrix[i].length, original.matrix[i].length); j++)
				matrix[i][j].assign(original.matrix[i][j]);
	}
	
	public Real det()
	{	
		if(getH()==2 && getW()==2)
		{
			tmp[2].assign(matrix[0][0]);
			tmp[2].mul(matrix[1][1]);
			
			tmp[1].assign(matrix[0][1]);
			tmp[1].mul(matrix[1][0]);
			
			tmp[2].sub(tmp[1]);
			return tmp[2];
		}
		else if(getH()==3 && getW()==3)
		{
			tmp[0].assign(matrix[0][0]);
			tmp[0].mul(matrix[1][1]);
			tmp[0].mul(matrix[2][2]);
			
			tmp[1].assign(matrix[0][1]);
			tmp[1].mul(matrix[1][2]);
			tmp[1].mul(matrix[2][0]);
			
			tmp[2].assign(matrix[0][2]);
			tmp[2].mul(matrix[1][0]);
			tmp[2].mul(matrix[2][1]);
			
			tmp[3].assign(matrix[0][2]);
			tmp[3].mul(matrix[1][1]);
			tmp[3].mul(matrix[2][0]);
			
			tmp[4].assign(matrix[0][1]);
			tmp[4].mul(matrix[1][0]);
			tmp[4].mul(matrix[2][2]);
			
			tmp[5].assign(matrix[0][0]);
			tmp[5].mul(matrix[1][2]);
			tmp[5].mul(matrix[2][1]);
			
			tmp[6].assign(tmp[0]);
			tmp[6].add(tmp[1]);
			tmp[6].add(tmp[2]);
			tmp[6].sub(tmp[3]);
			tmp[6].sub(tmp[4]);
			tmp[6].sub(tmp[5]);
			
			return tmp[6];
		}
		return Real.NAN;
	}
}
